package work.thread_eg.thread0.pool0;

import lombok.SneakyThrows;

import java.util.concurrent.*;


/**
 * Runnable接口 +  线程池ExecutorService  实现多线程
 *
 * ExecutorService接口
 *      submit()方法 同样可以提交Runnable接口的线程实现类 但是返回值是由submit()方法的第二个参数值提供的
 *          这样子的主要的目的是利用Future接口的get()方法阻塞  所以返回对象Future的值反而不重要
 *
 */
public class RunnablePool {
    public static void main(String[] args) {
        RunnablePool runnablePool = new RunnablePool();

        // 执行任务
        runnablePool.work();
    }

    public void work() {
        // 开始时间
        long begin = System.currentTimeMillis();

        // 可缓存线程池
        ExecutorService threadPool = Executors.newCachedThreadPool();

        // 实现了Callable接口的线程类
        MyRunnable myRunnable1 = new MyRunnable();

        // 1 submit()提交
        Future<Integer> future1 = threadPool.submit(myRunnable1,200);

        // 2 提前创建FutureTask对象 之后execute()执行线程
        FutureTask<Integer> futureTask2 = new FutureTask<>(myRunnable1, 400);
        threadPool.execute(futureTask2);

        try {
            System.out.println("get() 之前");
            // get方法会阻塞主线程
            Integer sum1 = future1.get();
            System.out.println("get() 之后");
            System.out.println("线程1 的结果：" + sum1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }

        // 结束时间
        System.out.println(System.currentTimeMillis() - begin + "毫秒");
    }

    /**
     * 线程类
     *
     */
    class MyRunnable implements Runnable {

        @SneakyThrows
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + "正在执行");
            // 线程沉睡3秒
            TimeUnit.SECONDS.sleep(5);
        }
    }

}
